<template>
  <n-list hoverable clickable>
    <draggable
      class="draggable-box"
      v-model="localNodes"
      group="label"
      item-key="key"
      :animation="200"
      :force-fallback="true"
      :handle="'.list-icon'"
      @start="onDragStart"
      @end="onDragEnd"
    >
      <template #item="{ element }">
        <TreeNode
          :node="element"
          :parent-node="rootNode"
          :level="0"
          :selected-key="selectedKey"
          @load-children="handleLoadChildren"
          @select="handleSelect"
          @insert="handleInsert"
          @delete="deleteNode"
          @update="updateNode"
          @drag-end="onChildDragEnd"
        />
      </template>
    </draggable>
  </n-list>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import draggable from 'vuedraggable'
import TreeNode from './TreeNode.vue'
import { useMessage } from 'naive-ui'

interface TreeNodeData {
  key: string | number
  parentKey: string | number
  groupId: string | number
  type: string
  label?: string
  children?: TreeNodeData[]
  pids?: Array<string | number>
}

const props = defineProps<{
  nodes: TreeNodeData[]
  selectedKey: Array<string | number>
  handleLoadChildren: (node: TreeNodeData) => Promise<void>
  select: (node: TreeNodeData) => Promise<void>
  addNode: (node: TreeNodeData) => Promise<void>
  deleteNode: (node: TreeNodeData) => Promise<void>
  updateNode: (node: TreeNodeData) => Promise<void>
  updateNodeSort: (nodes: TreeNodeData[]) => Promise<void>
  updateBooksSort: (nodes: TreeNodeData[]) => Promise<void>
}>()

const message = useMessage()

const emit = defineEmits(['update:selectedKey'])

const localNodes = ref<TreeNodeData[]>(props.nodes)
const rootNode = ref<TreeNodeData>({
  key: 'root',
  groupId: "",
  parentKey: '',
  type: 'root',
  children: localNodes.value
})

// 同步外部变化
watch(
  () => props.nodes,
  (v) => {
    localNodes.value = v ?? []
    rootNode.value.children = localNodes.value
  },
  { deep: true }
)

function handleSelect(node: TreeNodeData) {
  emit('update:selectedKey', node.key)
  props.select(node)
}

// 拖拽开始
function onDragStart(_evt: any) {
  message.info('只能同级节点之间拖拽排序')
}

// 拖拽结束
function onDragEnd(evt: any) {
  const { oldIndex, newIndex } = evt
  if (oldIndex !== newIndex) {
    updateNodeSort(localNodes.value)
    updateBooksSort(localNodes.value)
  }
}


// 拖拽结束
function onChildDragEnd(payload: { parentKey: string | number; children: TreeNodeData[] }) {
  console.log(localNodes.value);
  
  const { parentKey, children } = payload
  for (const key in children) {
    children[key].parentKey = parentKey;
    
  }
  updateNodeSort(children)
}

const handleLoadChildren = props.handleLoadChildren
function handleInsert(node: TreeNodeData) {
  props.addNode(node) // 调用传入的 addNode 方法
}
const deleteNode = props.deleteNode
const updateNode = props.updateNode
const updateNodeSort = props.updateNodeSort
const updateBooksSort = props.updateBooksSort
</script>

<style scoped>
.n-list {
  user-select: none;
}
</style>
